package cn.com.cifi.mars.service.impl;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import cn.com.cifi.mars.bean.bo.SysLogBO;
import cn.com.cifi.mars.bean.dto.DivisionDto;
import cn.com.cifi.mars.bean.dto.ProjectByStagesDto;
import cn.com.cifi.mars.bean.vo.sys.rsp.CityVo;
import cn.com.cifi.mars.bean.vo.sys.rsp.ProjectByStagesVo;
import cn.com.cifi.mars.bean.vo.sys.rsp.ProjectVo;
import cn.com.cifi.mars.bean.vo.sys.rsp.RegionVo;
import cn.com.cifi.mars.bean.vo.sys.rsp.StagesVo;
import cn.com.cifi.mars.common.base.BaseServiceImpl;
import cn.com.cifi.mars.constant.Constants;
import cn.com.cifi.mars.constant.HrOrgTypeEunm;
import cn.com.cifi.mars.constant.IsSuccessEnum;
import cn.com.cifi.mars.constant.LogEventEnum;
import cn.com.cifi.mars.constant.LogSrcEnum;
import cn.com.cifi.mars.constant.LogTypeEnum;
import cn.com.cifi.mars.entity.common.IdmOrg;
import cn.com.cifi.mars.entity.common.ProjectByStages;
import cn.com.cifi.mars.mapper.mars.IdmOrgMapper;
import cn.com.cifi.mars.mapper.mars.ProjectByStagesMapper;
import cn.com.cifi.mars.service.OrgService;
import cn.com.cifi.mars.service.SysLogService;
import cn.com.cifi.mars.util.BasicAuthClient;
import cn.com.cifi.mars.util.FieldUtils;
import cn.com.cifi.mars.util.StrUtils;
import cn.com.cifi.mars.util.WebUtils;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class OrgServiceImpl extends BaseServiceImpl<IdmOrg> implements OrgService {

	@Autowired
	private IdmOrgMapper orgMapper;
	@Autowired
	private ProjectByStagesMapper projectByStagesMapper;
	@Autowired
	private SysLogService sysLogService;

	@Value("${host}")
	private String host;
	
	@Value("${port_idm}")
	private String portIdm;
	
	@Value("${api_name}")
	private String apiName;
	
	@Value("${api_key}")
	private String apiKey;
	
	
	private Map<String,IdmOrg> parentOrgsMap = new HashMap<String,IdmOrg>();
	
	@Override
	public List<String> getOrgdepidList() {
		return orgMapper.selectOrgdepidList();
	}

	@Override
	@Transactional
	public List<String> incrementSyncIdmOrg(String orgdepid, String timestamp, String cookie, List<String> orgdepids,List<String> projectIds) {
        BasicAuthClient bac = new BasicAuthClient();
		String url = host+"/idm/orgs/pagingquery?filter=";
        String filter="(&(orgdepid="+orgdepid+")(|(createtime>="+timestamp+")(modifytimestamp>="+timestamp+")))";
        try {
			filter = URLEncoder.encode(filter, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
        if ("0".equals(cookie)) {
            filter += "&pageSize=" + 1000;
        } else {
            filter += "&pageSize=" + 1000 + "&cookie=" + cookie;
        }
        String result = bac.get(url, filter, apiName, apiKey);
        log.info("######### 同步组织机构数据请求参数："+url+filter);
        //同步数据
        JSONObject jsonObject = JSONObject.parseObject(result);
        JSONObject resultInfo = jsonObject.getJSONObject("resultInfo");
        if(resultInfo != null) {
        	String returnMsg = resultInfo.getString("success");
            if (returnMsg.equals("true")) {
                List<IdmOrg> addList = new ArrayList<>();
                List<IdmOrg> updateList = new ArrayList<>();
                JSONObject body =resultInfo.getJSONObject("body");
                JSONArray wsOrgs =(JSONArray) body.get("wsOrgs");
                if(wsOrgs!= null && !wsOrgs.isEmpty()) {
                	 for(int i=0; i<wsOrgs.size();i++ ) {
                     	JSONObject wsOrg = (JSONObject) wsOrgs.get(i);
                     	JSONArray attributesArray = (JSONArray) wsOrg.get("attributes");
                     	IdmOrg idmOrg = new IdmOrg();
                     	 for (int k = 0; k < attributesArray.size(); k++) {
                              JSONObject kObj = attributesArray.getJSONObject(k);
                              String name = kObj.get("name").toString().replaceAll("-", "_");
                              String value = "";
                              if (kObj.get("value") != null) {
                                  value = kObj.get("value").toString();
                              }
                              if (kObj.get("values") != null) {
                                  value = kObj.get("values").toString();
                              }
                              FieldUtils.setProperty(idmOrg, name.replaceAll("-", "_"), value);
                          }
                     	
                     	 if(CollectionUtils.isEmpty(orgdepids)) {
                     		addList.add(idmOrg);
                     	 }else {
                     		if(orgdepids.contains(idmOrg.getOrgdepid())) {
                               	updateList.add(idmOrg);
                            }else {
                               	addList.add(idmOrg);
                            }
                     	 }
                     	 
                     	 if(StrUtils.isNotEmpty(idmOrg.getHrOrgType()) && "项目".equals(idmOrg.getHrOrgType())) {
                     		projectIds.add(idmOrg.getOrgdepid());
                     	 }
                     	 
                     }
                	 //批量新增
                     if(CollectionUtils.isNotEmpty(addList)) {
                    	 orgMapper.insertList(addList);
                     }
                     //批量修改
                     if(CollectionUtils.isNotEmpty(updateList)) {
                    	 orgMapper.updateDataBatch(updateList);
                     }
                     String addStr = getIdmOrg(addList);
                     String updateStr = getIdmOrg(updateList);
                     saveLog("请求参数：" + url+filter + ";响应数据：新增组织机构：" + addStr+"&&更新组织机构："+updateStr,"同步IDM组织机构","同步数据");
                     
                     //继续分页拉取
                     String cookies =body.getString("cookie");
                     //是否最后一页
                     if (StrUtils.isNotEmpty(cookies)) {
                     	incrementSyncIdmOrg(orgdepid,timestamp,cookies,orgdepids,projectIds);
                     }
                }
            }
        }
        return projectIds;
	}
	
	 private String getIdmOrg(List<IdmOrg> addList) {
		StringBuilder sb = new StringBuilder();
    	for(IdmOrg org : addList) {
    		sb.append(org.getOrgdepid()).append("~").append(org.getOrgname()).append(";");
		}
		return sb.toString();
	 }

	/**
	 * 获取组织机构树
	 */
	@Override
	public JSONArray queryOrgTreeList() {
		List<IdmOrg> list=orgMapper.selectOrgList("");
		List<IdmOrg> listTree=buildTree(list,"00000000");
		JSONArray trssJson= JSONArray.parseArray(JSON.toJSONString(listTree));
		return trssJson;
	}
	
	/**
	 * 递归子节点
	 * @param list
	 * @param parentId
	 * @return
	 */
	public static List<IdmOrg> buildTree(List<IdmOrg> list,String id){
		List<IdmOrg> menus=new ArrayList<IdmOrg>();
	    for (IdmOrg menu : list) {  
	    	  //本身id
	          String menuId = menu.getOrgdepid();
	          //父id
	          String pid = menu.getParentOrgid();
	          if (id.equals(pid)) {  
	              List<IdmOrg> menuLists = buildTree(list, menuId);  
	              menu.setChildMenu(menuLists);
	              menus.add(menu);  
	          }  
	    }  
		return menus;
	}

	/**
	 * 递归项目的组织机构
	 * @param allOrgList
	 * @param orgId
	 * @return
	 */
	private Map<String,IdmOrg> getParentOrgs(List<IdmOrg> allOrgList, String orgId) {
		for (IdmOrg org : allOrgList) {
			// 判断是否存在父节点
			if (org.getOrgdepid().equals(orgId)) {
				// 递归遍历上一级
				getParentOrgs(allOrgList, org.getParentOrgid());
				parentOrgsMap.put(org.getOrgdepid(), org);
			}
		}
		return parentOrgsMap;
	}
	
	String line= "-";
	/**
	 * 遍历所有项目
	 * @param allOrgs
	 * @param projects
	 * @return
	 */
	private Map<String,IdmOrg> getAllProjects(List<IdmOrg> allOrgs, List<IdmOrg> projects) {
		//遍历所有项目
		for (IdmOrg org : projects) {
			String projectOrgId = org.getOrgdepid();
			//遍历每个项目的所有父级Org
			getParentOrgs(allOrgs, projectOrgId);
		}
		return parentOrgsMap;
	}


	/**
	 * 项目分期树形菜单
	 */
	@Override
	public JSONArray queryStagesTreeList() {
		List<ProjectByStages> list=projectByStagesMapper.selectStagesList();
		List<ProjectByStages> listTree=buildStagesTree(list,"00000000");
		JSONArray trssJson= JSONArray.parseArray(JSON.toJSONString(listTree));
		return trssJson;
	}
	
	/**
	 * 递归项目分期子节点
	 * @param list
	 * @param parentId
	 * @return
	 */
	public static List<ProjectByStages> buildStagesTree(List<ProjectByStages> list,String parentId){
		List<ProjectByStages> menus=new ArrayList<ProjectByStages>();
	    for (ProjectByStages menu : list) {  
	    	  //本身id
	          String menuId = menu.getOrgdepid();
	          //父id
	          String pid = menu.getParentOrgid();
	          if (parentId.equals(pid)) {  
	              List<ProjectByStages> menuLists = buildStagesTree(list, menuId);  
	              menu.setChildren(menuLists);
	              menus.add(menu);  
	          }  
	    }  
		return menus;
	}

	
	/**
	 * 显示区域下拉框
	 */
	@Override
	public List<RegionVo> queryRegionList() {
		List<RegionVo>voList=new ArrayList<>();
		List<Map<String,Object>>list=orgMapper.selectRegionList(HrOrgTypeEunm.ORG_20.getKey());
		list.forEach(x->{
			String regionName=x.get("regionName").toString();
			String regionId=x.get("regionId").toString();
			RegionVo vo=new RegionVo();
			vo.setRegionId(regionId);
			vo.setRegionName(regionName);
			voList.add(vo);
		});
		return voList;
	}
	
	/**
	 * 项目分期v1版本
	 */
	@Override
	public ProjectByStagesVo queryProjectByStagesV1() {
		ProjectByStagesVo vo=new ProjectByStagesVo();
		////组织机构 项目 分期 城市公司 事业部 类型
		List<String>stringList=new ArrayList<>();
		stringList.add(HrOrgTypeEunm.ORG_20.getKey());
		stringList.add(HrOrgTypeEunm.ORG_21.getKey());
		stringList.add(HrOrgTypeEunm.ORG_23.getKey());
		stringList.add(HrOrgTypeEunm.ORG_31.getKey());
		stringList.add(HrOrgTypeEunm.ORG_32.getKey());
		List<ProjectByStagesDto>list=orgMapper.selectProjectByStagesV1(Constants.ORGSTATUS,stringList);
		vo.setList(list);
		return vo;
	}


	/**
	 * 全量拉取主数据(mdm新表)项目到本地项目分期表(前端勿动)
	 */
	@Transactional
	@Override
	public int addByStagesV2() {
		List<IdmOrg> orgList = orgMapper.selectOrgList("");
		List<IdmOrg> projeOrgList = orgMapper.selectMdmProjectList();
		List<ProjectByStages> dataList = Collections.synchronizedList(new ArrayList<>());
		parentOrgsMap = new HashMap<String, IdmOrg>();
		// 项目以上的数据
		Map<String, IdmOrg> orgMap = getAllProjects(orgList, projeOrgList);
		// 项目分期的数据
		List<IdmOrg> byStagesList = orgMapper.selectPhasesUnderProjectsList();
		for (int i = 0; i < byStagesList.size(); i++) {
			ProjectByStages record = new ProjectByStages();
			BeanUtils.copyProperties(byStagesList.get(i), record);
			String parentOrgid=record.getParentOrgid();
			String orgnamefullpath=record.getOrgnamefullpath();
			String orgnofullpath=record.getOrgnofullpath();
			//不存在全路径,查询项目
			if(!orgnofullpath.contains("-")) {
				//不存在全路径,查询项目
				IdmOrg im=orgMapper.selectByOrgdepId(parentOrgid);
				if(im!=null) {
					orgnamefullpath=im.getOrgnamefullpath()+"-"+orgnamefullpath;
					orgnofullpath=im.getOrgnofullpath()+"-"+orgnofullpath;
					record.setOrgnamefullpath(orgnamefullpath);
					record.setOrgnofullpath(orgnofullpath);
				}
			}
			dataList.add(record);
		}

		for (IdmOrg idmOrg : orgMap.values()) {
			ProjectByStages record = new ProjectByStages();
			BeanUtils.copyProperties(idmOrg, record);
			// 类型不为空 才能添加到本地项目分期树表
			boolean flag=true;
			if(StringUtils.isNotBlank(idmOrg.getHrOrgTypeId())) {
				//主数据项目名称不为空才添加到项目分期表中
				if(StringUtils.isNotBlank(idmOrg.getProjectName())){
					record.setOrgname(idmOrg.getProjectName());
				}
				String [] orgnofullpaths=idmOrg.getOrgnofullpath().split("-");
				if(idmOrg.getHrOrgTypeId().equals(HrOrgTypeEunm.ORG_31.getKey())) {
					//3是城市公司
					String parentOrgid=orgnofullpaths[3];
					record.setParentOrgid(parentOrgid);
				}
				//判断当前类型是不是城市公司和直管项目
				if(idmOrg.getHrOrgTypeId().equals(HrOrgTypeEunm.ORG_20.getKey())||
						idmOrg.getHrOrgTypeId().equals(HrOrgTypeEunm.ORG_21.getKey())||
						idmOrg.getHrOrgTypeId().equals(HrOrgTypeEunm.ORG_23.getKey())) {
					int count=orgMapper.selectByStages(HrOrgTypeEunm.ORG_32.getKey(), record.getOrgdepid());
					if(count==0) {
						//不允许添加
						flag=false;
					}
				}
			}else {
				flag = false;
			}
			if(flag) {
				dataList.add(record);
			}
		}
		
		// 删除分期表数据
		projectByStagesMapper.deleteAll();
		projectByStagesMapper.insetBatch(dataList);
		return 1;
	}


	/**
	 * 获取城市信息
	 */
	@Override
	public List<CityVo> queryCityList(String regionId) {
		return orgMapper.selectCityList(Constants.ORGSTATUS, HrOrgTypeEunm.ORG_21.getKey(),regionId);
	}

	/**
	 * 项目下拉框
	 */
	@Override
	public List<ProjectVo> queryProject(String regionId) {
		List<String>str=new ArrayList<String>();
		str.add(HrOrgTypeEunm.ORG_23.getKey());
		str.add(HrOrgTypeEunm.ORG_31.getKey());
		return projectByStagesMapper.selectProjectList(regionId,str);
	}
	
	/**
	 * 分期下拉框
	 */
	@Override
	public List<StagesVo> queryStagesList(String projectId) {
		return projectByStagesMapper.selectStagesVoList(projectId,HrOrgTypeEunm.ORG_32.getKey());
	}
	
	/**
	 * 流程配置左侧组织机构
	 */
	@Override
	public JSONArray queryProcessConfigTree() {
		List<String> hrOrgTypeIds=new ArrayList<>();
		hrOrgTypeIds.add(HrOrgTypeEunm.ORG_20.getKey());
		hrOrgTypeIds.add(HrOrgTypeEunm.ORG_21.getKey());
		List<ProjectByStages> list=orgMapper.selectProcessConfigTree(hrOrgTypeIds);
		List<ProjectByStages> listTree=buildStagesTree(list,Constants.XUHUI_GROUP);
		JSONArray trssJson= JSONArray.parseArray(JSON.toJSONString(listTree));
		return trssJson;
	}
	
	
	/**
	 * 添加日志
	 * @param module
	 * @param title
	 * @param content
	 */
	private void saveLog(String content,String title,String module) {
        SysLogBO bo = new SysLogBO();
        bo.setEvent(LogEventEnum.BROWSE);
        bo.setSource(LogSrcEnum.SYS);
        String hostAddr =WebUtils.getLocalIP();
        bo.setIp(hostAddr);
        bo.setModule(module);
        bo.setTitle(title);
        bo.setContent(content);
        bo.setType(LogTypeEnum.ONE.getKey());
        bo.setIsSuccess(IsSuccessEnum.SUCCESS.getKey());
        sysLogService.add(bo,Constants.SYS);
    }


	@Override
	public List<DivisionDto> getOrgList(String key) {
		return projectByStagesMapper.getOrgList(key);
	}


	@Override
	public List<DivisionDto> getDivisionList(List<String> divisionIdList) {
		return projectByStagesMapper.selectDivisionList(divisionIdList);
	}
	
}
